#pragma once
#include <cctype>
#include <map>
#include <stdexcept>
#include <string>
#include <utility>

/*  
 * URI: scheme:[//[user:password@]domain[:port]][/]path[?query][#fragment]
 */
namespace utils
{
    struct URI
    {
        enum Error
        {
            Ok = 0,
            Uninitialized,
            NoUrlCharacter,
            InvalidSchemeName,
            NoDoubleSlash,
            NoAtSign,
            NoSlash,
        };
        Error error{Uninitialized};
        std::string scheme{};
        std::string username{};
        std::string password{};
        std::string host{};
        uint16_t port{};
        std::string path{};
        std::string query{};
        std::string fragment{};

        URI() = default;
        explicit URI(const std::string& uri);

        static URI file(const std::string& path);

        static URI fromPlatform(const std::string& uri);

        [[nodiscard]] bool isFile() const { return "file" == scheme; }

        [[nodiscard]] std::string toString() const;

        [[nodiscard]] std::string toPlatform() const;
    };
}; // namespace utils
